import { SkillBase } from '@/assets/scripts/skill/SkillBase'
import { GameObject } from '@/assets/scripts/GameObject'

export class Fireball extends SkillBase {
    //info包含火球信息, player(发射火球的player), x, y, vx, vy, radius, color, speed, range, damage
    constructor(player) {
        super(player, 3) // 设置冷却时间为3秒
        this.player = player
        this.skillKey = 'q'
        this.skillName = 'fireball'
        this.damage = 20
        this.speed = player.info.speed * 3.0
        this.range = player.height
        this.radius = player.height * 0.01
        this.color = 'rgba(255, 100, 0, 0.9)' // 添加默认颜色
        this.id = 'fireball_' + Math.random().toString(36).substr(2, 9) // 为每个火球生成唯一ID
        this.hasHit = false // 新增命中状态标记
        // 用于记录哪些玩家已经被这个火球击中过，防止多次伤害
        this.hitPlayers = new Set()

         // 加载火球技能图标
        this.load_icon('https://www.helloimg.com/i/2025/04/11/67f8dff24aa8d.jpg')
    }
    cast(tx, ty) {
        // 如果玩家死亡，不允许发射
        if (this.player.is_dead) {
            return false
        }
        
        // 调用父类的cast方法检查冷却
        if (!super.cast()) {
            return false
        }

        try {
            // 计算方向向量
            const angle = Math.atan2(ty - this.player.info.y, tx - this.player.info.x)
            const vx = Math.cos(angle)
            const vy = Math.sin(angle)

            // 创建火球实体
            const fireball = this.createFireballEntity(vx, vy)
            
            // 如果创建成功，返回true
            return fireball !== null
        } catch (error) {
            console.error("发射火球失败:", error)
            return false
        }
    }
    createFireballEntity(vx, vy) {
        // 确保玩家和游戏地图存在
        if (!this.player || !this.gameMap) {
            console.error("创建火球失败：玩家或游戏地图不存在");
            return null;
        }
        
        try {
            // 创建新的火球实体
            return new FireballEntity(this.gameMap, {
                x: this.player.info.x,
                y: this.player.info.y,
                vx: vx,
                vy: vy,
                radius: this.radius,
                color: this.color,
                speed: this.speed,
                range: this.range,
                damage: this.damage,
                player: this.player,
            });
        } catch (error) {
            console.error("创建火球实体时出错:", error);
            return null;
        }
    }
}
class FireballEntity extends GameObject {
    constructor(gameMap, info) {
        super()
        this.gameMap = gameMap
        this.info = info
        this.eps = 0.1
        this.hasHit = false // 标记是否已击中目标
        this.id = 'fireball_entity_' + Math.random().toString(36).substr(2, 9)
    }
    start() {}

    // 计算两点之间的距离
    get_dist(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
    }

    // 判断是否与玩家碰撞
    is_collision(player) {
        let distance = this.get_dist(player.info.x, player.info.y, this.info.x, this.info.y)
        // 使用0.8的碰撞系数让碰撞检测更精确
        const collisionFactor = 0.8
        if (distance < (this.info.radius + player.info.radius) * collisionFactor) return true
        return false
    }
    
    // 攻击玩家
    attack(player) {
        let angle = Math.atan2(player.info.y - this.info.y, player.info.x - this.info.x)

        // 检查是否在SingleMap模式下，如果是则直接在前端处理伤害
        if (this.gameMap.constructor.name === 'SingleMap') {
            player.is_attacked(angle, this.info.damage)
        } else if (this.gameMap.gameStore && this.gameMap.gameStore.socket) {
            // 联机模式下，发送火球击中事件到后端
            // 生成命中事件ID以帮助服务器去重
            const hitId = this.id + '_' + player.info.userId + '_' + Date.now()

            // 创建火球命中消息
            const hitMessage = {
                event: 'fireball-hit',
                attackerId: this.info.player.info.userId, // 攻击者ID
                targetId: player.info.userId, // 被击中的玩家ID
                fireballX: this.info.x / this.gameMap.width, // 火球相对位置X
                fireballY: this.info.y / this.gameMap.height, // 火球相对位置Y
                hitId: hitId, // 命中ID用于去重
            }

            // 发送到服务器
            this.gameMap.gameStore.socket.send(JSON.stringify(hitMessage))
        }

        this.hasHit = true // 标记已击中
        this.destroy() // 攻击后立即销毁火球
    }
    
    // 根据游戏地图大小重新调整火球的大小和速度
    resize(widthRatio, heightRatio) {
        // 按比例缩放位置
        this.info.x *= widthRatio
        this.info.y *= heightRatio

        // 按比例缩放半径和其他属性
        this.info.radius *= heightRatio
        this.info.speed *= heightRatio
        this.info.range *= heightRatio
    }

    update() {
        // 如果火球已经击中目标或者超过射程，则销毁火球
        if (this.info.range < this.eps || this.hasHit) {
            this.destroy()
            return false
        }

        // 计算本帧移动距离（取剩余射程和速度计算距离的较小值）
        let moved = Math.min(this.info.range, (this.info.speed * this.timedelta) / 1000)
        // 更新火球位置（根据速度方向向量移动）
        this.info.x += this.info.vx * moved
        this.info.y += this.info.vy * moved
        // 减少剩余射程
        this.info.range -= moved

        // 碰撞检测
        for (let i = 0; i < this.gameMap.players.length; i++) {
            let player = this.gameMap.players[i]
            // 检查玩家是否已死亡，以及是否是发射火球的玩家自己
            if (
                this.info.player !== player &&
                !player.is_dead &&
                this.is_collision(player)
            ) {
                // 如果此火球尚未击中任何玩家，则攻击此玩家
                if (!this.hasHit) {
                    this.attack(player)
                    return // 攻击后立即结束更新
                }
                break
            }
        }

        // 如果没有碰撞则继续渲染
        if (!this.hasHit) {
            this.render()
        }
    }
    // 修改销毁方法
    destroy() {
        // 清除所有关联数据
        super.destroy()
    }

    render() {
        // 如果已击中则不渲染
        if (this.hasHit) return

        // 检查是否有context
        if (!this.gameMap || !this.gameMap.ctx) {
            console.warn('无法渲染火球：缺少gameMap或ctx')
            return
        }

        try {
            // 绘制火球外圈
            this.gameMap.ctx.beginPath()
            this.gameMap.ctx.fillStyle = this.info.color
            this.gameMap.ctx.arc(this.info.x, this.info.y, this.info.radius, 0, Math.PI * 2)
            this.gameMap.ctx.fill()

            // 添加发光效果
            this.gameMap.ctx.beginPath()
            this.gameMap.ctx.fillStyle = 'rgba(255, 255, 0, 0.5)'
            this.gameMap.ctx.arc(this.info.x, this.info.y, this.info.radius * 0.5, 0, Math.PI * 2)
            this.gameMap.ctx.fill()

            // 添加火球尾部拖尾效果
            this.gameMap.ctx.beginPath()
            this.gameMap.ctx.strokeStyle = 'rgba(255, 100, 0, 0.7)'
            this.gameMap.ctx.lineWidth = this.info.radius * 0.5
            this.gameMap.ctx.moveTo(this.info.x, this.info.y)
            this.gameMap.ctx.lineTo(
                this.info.x - this.info.vx * this.info.radius * 3,
                this.info.y - this.info.vy * this.info.radius * 3
            )
            this.gameMap.ctx.stroke()
        } catch (error) {
            console.error('渲染火球时出错：', error)
        }
    }

    // 清理火球资源
    on_destroy() {
        // 确保清理所有引用
        this.info = null;
        this.gameMap = null;
    }
}
